package asdf.springmvc;

import org.apache.commons.codec.binary.Base64;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.Charset;
import java.security.Key;
import java.util.Arrays;

public class CryptUtils {

    private static final Key cryptKey = new SecretKeySpec("ShowMe$The$Money".getBytes(), "AES");
    private static final String ALGORITHM = "AES/ECB/NoPadding";
    private static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");

    public static byte[] aesEncrypt(byte[] bytes) {
        if (bytes == null || bytes.length == 0) {
            return bytes;
        }
        if (bytes.length % 16 != 0) {
            byte[] fixedBytes = new byte[(bytes.length / 16 + 1) * 16];
            System.arraycopy(bytes, 0, fixedBytes, 0, bytes.length);
            Arrays.fill(fixedBytes, bytes.length, fixedBytes.length - 1, (byte) 0);
            bytes = fixedBytes;
        }
        try {
            return getCipher(true).doFinal(bytes);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static byte[] aesDecrypt(byte[] bytes) {
        if (bytes == null || bytes.length == 0) {
            return bytes;
        }
        try {
            return getCipher(false).doFinal(bytes);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static String encryptText(String plaintext) {
        return Base64.encodeBase64String(aesEncrypt(plaintext.getBytes(DEFAULT_CHARSET)));
    }

    public static String decryptText(String ciphertext) {
        return new String(aesDecrypt(Base64.decodeBase64(ciphertext.getBytes(DEFAULT_CHARSET))));
    }

    private static final ThreadLocal<Cipher> ENCRYPT_CIPHERS = new ThreadLocal<>();
    private static final ThreadLocal<Cipher> DECRYPT_CIPHERS = new ThreadLocal<>();

    private static Cipher getCipher(boolean isEncryt) {
        ThreadLocal<Cipher> cipherCache = isEncryt ? ENCRYPT_CIPHERS : DECRYPT_CIPHERS;
        Cipher cipher = cipherCache.get();
        if (cipher == null) {
            try {
                cipher = Cipher.getInstance(ALGORITHM);
                cipher.init(isEncryt ? Cipher.ENCRYPT_MODE : Cipher.DECRYPT_MODE, cryptKey);
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
            cipherCache.set(cipher);
        }
        return cipher;
    }
    
    public static void main(String[] args) {
		String s = "wayne";
		System.out.println(encryptText(s));
	}

}
